package zclTool;

import java.util.Arrays;
import java.util.*;
import java.io.*;

public class StrCmp {

	static HashSet<String> stopwords = new HashSet<String>();
	boolean stemmer = false;
	Stemmer stm;

	public StrCmp(boolean stemmer) {
		try {
			Class c = StrCmp.class;
			InputStream dicFile = c.getResource("stopwords").openStream();
			BufferedInputStream in = new BufferedInputStream(dicFile);
			BufferedReader br = new BufferedReader(new InputStreamReader(in,
					"utf-8"));
			String line = "";
			while ((line = br.readLine()) != null) {
				if (line.length() >= 1) {
					stopwords.add(line);
				}
			}
			br.close();
		} catch (Exception e) {

		}
		this.stemmer = stemmer;
		if (stemmer) {
			stm = new Stemmer();
		}
	}

	private int Minimum(int a, int b, int c) {
		int mi;

		mi = a;
		if (b < mi) {
			mi = b;
		}
		if (c < mi) {
			mi = c;
		}
		return mi;

	}

	// *****************************
	// Compute Levenshtein distance
	// *****************************

	public int Levenshtein_distance(String s, String t) {
		int d[][]; // matrix
		int n; // length of s
		int m; // length of t
		int i; // iterates through s
		int j; // iterates through t
		char s_i; // ith character of s
		char t_j; // jth character of t
		int cost; // cost

		// Step 1

		n = s.length();
		m = t.length();
		if (n == 0) {
			return m;
		}
		if (m == 0) {
			return n;
		}
		d = new int[n + 1][m + 1];

		// Step 2

		for (i = 0; i <= n; i++) {
			d[i][0] = i;
		}

		for (j = 0; j <= m; j++) {
			d[0][j] = j;
		}

		// Step 3

		for (i = 1; i <= n; i++) {

			s_i = s.charAt(i - 1);

			// Step 4

			for (j = 1; j <= m; j++) {

				t_j = t.charAt(j - 1);

				// Step 5

				if (s_i == t_j) {
					cost = 0;
				} else {
					cost = 1;
				}

				// Step 6

				d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1,
						d[i - 1][j - 1] + cost);

			}

		}

		// Step 7

		return d[n][m];

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String a = removePunc("i'am,wu\ty444");
		System.out.println(a);
		StrCmp sc = new StrCmp(true);
		List<String> x = sc
				.str2list("The problem is more complex than you think. Are you absolutely sure than you're only ever going to process English text?");
		int xx = sc.sharewords("my father is great!",
				"there are many great fathers there!");
		double xy = sc.sharewordsRatio("my father is great!",
				"there are many great fathers there!");
		System.out.println(xy);
	}

	public static String removePunc(String a) {
		return a.replace("_", " ").replaceAll("[^a-zA-Z0-9']", " ");
	}

	public List<String> str2list(String a) {
		String aa = removePunc(a).toLowerCase();
		String[] aalist = aa.split("\\s|\\'");
		List<String> res = new ArrayList<String>();
		for (String str : aalist) {
			if (stemmer) {
				str = stm.stemStr(str);
			}
			// if(!stopwords.contains(str) && str.length()>=2){
			// res.add(str);
			// }
			if (str.length() > 1) {
				res.add(str);
			}
		}
		Collections.sort(res);
		return res;
	}

	public int sharewords(String a, String b) {
		Object[] alist = this.str2list(a).toArray();
		Object[] blist = this.str2list(b).toArray();
		int i = 0, j = 0;
		int same = 0;
		while (i < alist.length && j < blist.length) {
			String a0 = (String) alist[i];
			String b0 = (String) blist[j];
			if (a0.equals(b0)) {
				same++;
				i++;
				j++;
			} else if (a0.compareTo(b0) > 0) {
				j++;
			} else {
				i++;
			}
		}
		return same;
	}

	/**
	 * ablen is a lenght 2 int array, ablen[0] is the number of words in a,
	 * ablen[1] is the number of words in b
	 */
	public int sharewords(String a, String b, int[] ablen) {
		Object[] alist = this.str2list(a).toArray();
		Object[] blist = this.str2list(b).toArray();
		int i = 0, j = 0;
		int same = 0;
		while (i < alist.length && j < blist.length) {
			String a0 = (String) alist[i];
			String b0 = (String) blist[j];
			if (a0.equals(b0)) {
				same++;
				i++;
				j++;
			} else if (a0.compareTo(b0) > 0) {
				j++;
			} else {
				i++;
			}
		}
		ablen[0] = alist.length;
		ablen[1] = blist.length;
		return same;
	}

	// the ratio of common words, number of share words divided by the longer
	// length
	public double sharewordsRatio(String a, String b) {
		int ablen[] = new int[2];
		int same = sharewords(a, b, ablen);
		int longer = Math.max(ablen[1], ablen[0]);
		return same * 1.0 / longer;

	}

}
